import random

from django.http import HttpResponse
from django.shortcuts import render

# Create your views here.
from django_redis import get_redis_connection
from rest_framework import status
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework.views import APIView
from meiduo_mall.libs.captcha.captcha import captcha
from users.models import User

from verifications import constants
from verifications.serializers import ImageCodeCheckSerializer
from meiduo_mall.utils.yuntongxun.sms import CCP
import logging
from celery_tasks.sms.tasks import send_sms_code

logger = logging.getLogger('django')

# url('^image_codes/(?P<image_code_id>[\w-]+)/$', views.ImageCodeView.as_view())
# url信息:url('^image_codes/(?P<image_code_id>[\w-]+)/$')
# 图片验证码
class ImageCodeView(APIView):
    """这是图片验证码视图"""
    # 返回的是图片,不需要序列化器.验证码保存再redis中
    # 请求数据在路径中
    def get(self, request, image_code_id):
        # 生成验证码,利用工具生成图片验证码,拆包.
        text, image = captcha.generate_captcha()
        # 将验证码保存到redis中,配置中配置,链接redis仓库,记得修改redis的ip设置成自己的
        redis_conn = get_redis_connection('verify_codes')
        redis_conn.setex("img_%s" % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
        # 返回验证码图片, 使用原生的HttpResponse返回,可以渲染图片模板
        return HttpResponse(image, content_type='image/jpg')

# 短信验证码
# 访问方式: GET /sms_codes/(?P<mobile>1[3-9]\d{9})/?image_code_id=xxx&text=xxx
# url('^sms_codes/(?P<mobile>1[3-9]\d{9})/$', views.SMSCodeView.as_view()),
class SMSCodeView(GenericAPIView):
    """这是短信验证码的视图"""
    # 校验参数, 需要校验传送过来的查询字符串参数
    # 只用序列化器,不需要模型类数据
    serializer_class = ImageCodeCheckSerializer
    def get(self, request, mobile):
        # 校验参数,由序列化器完成
        serializer = self.get_serializer(data=request.query_params)
        serializer.is_valid(raise_exception=True)

        # 生成短信验证码
        sms_code = "%06d" % random.randint(0, 999999)
        # 保存短信验证码, 发送获取记录
        # 建立数据库链接
        redis_conn = get_redis_connection('verify_codes')
        # redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)

        # redis 管道,减少网络通信次数
        pl = redis_conn.pipeline()
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
        # 发送短信保存记录为1
        pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)
        # 执行,就执行一次
        pl.execute()


        # 发送短信验证码
        # try:
        #     ccp = CCP()
        #     result = ccp.send_template_sms(mobile, (sms_code, constants.SEND_SMS_CODE_INTERVAL//60), constants.SMS_CODE_TEMP_ID)
        # except Exception as e:
        #     logger.error('发送短信验证码异常[mobile:%s, message:%s]' % (mobile, e))
        #     return Response({'message': 'failed'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        # else:
        #     if result == 0:
        #         logger.info('发送短信验证码正常[mobile:%s]' % mobile)
        #         return Response({'message': 'ok'})
        #     else:
        #         logger.warning('发送短信验证码失败[mobile%s]' % mobile)
        #         # return Response({'message': 'failed'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        #         # 假装成功
        #         return Response({'message': 'ok'})

        # 使用celery发送短信验证码
        expires = constants.SEND_SMS_CODE_INTERVAL//60
        temp_id = constants.SMS_CODE_TEMP_ID
        # 发布任务到队列
        send_sms_code.delay(mobile, sms_code, expires, temp_id)
        # 运行:celery -A celery_tasks.main worker -l info

        # 直接返回我给你发了,不管能不能用
        return Response({'message': 'ok'})


# 判断用户是否存在
# url(r'^usernames/(?P<username>\w{5,20})/count/$', views.UsernameCountView.as_view()),
class UsernameCountView(APIView):
    """判断用户名数量"""
    def get(self, request, username):
        # 获取数据
        count = User.objects.filter(username=username).count()
        # 构造返回数据
        data = {
            'username': username,
            'count': count
        }

        # 返回数据
        return Response(data)


# 判断手机号是否存在
# GET/ mobile/(?P<mobile>1[3-9]\d{9})/count/
# url(r'^mobiles/(?P<mobile>1[3-9]\d{9})/count/$', views.MobileCountView.as_view()),
class MobileCountView(APIView):
    '''判断手机号码是否存在'''
    def get(self, request, mobile):
        # 取出参数,验证在正则中已经实现
        count = User.objects.filter(mobile=mobile).count()

        # 构造数据
        data = {
            'mobile': mobile,
            'count': count
        }

        return Response(data)

